﻿//========================================================= 
/**@file SM4CmdDriver.h
 * @brief SM4算法
 * 
 * @date 2017-05-12   21:10:39
 * @author Zhyioo 
 * @version 1.0
 */ 
//--------------------------------------------------------- 
#ifndef _LIBZHOUYB_SM4CMDDRIVER_H_
#define _LIBZHOUYB_SM4CMDDRIVER_H_
//--------------------------------------------------------- 
#include "../CommonCmdDriver.h"

#include "../../../extension/security/SM4_Provider.h"
using zhou_yb::extension::security::SM4_Provider;
//--------------------------------------------------------- 
namespace zhou_yb {
namespace application {
namespace driver {
//--------------------------------------------------------- 
class SM4CmdDriver : public CommonCmdDriver
{
public:
    SM4CmdDriver() : CommonCmdDriver()
    {
        _RegisteCMD(SM4CmdDriver, Encrypt);
        _RegisteCMD(SM4CmdDriver, Decrypt);
    }
    /**
     * @brief 加密数据
     * @date 2017-05-17 14:01
     * 
     * @param [in] KEY : hex 加密密钥(16字节)
     * @param [in] IV : hex [default:空] IV值(16字节)
     * @warning IV不存在或值为空时表示使用ECB方式
     *
     * @param [in] DATA : hex 需要加密的数据
     * 
     * @retval DATA : hex 加密后的数据
     */
    LC_CMD_METHOD(Encrypt)
    {
        string sKey = arg["KEY"].To<string>();
        string sData = arg["DATA"].To<string>();
        string sIV = arg["IV"].To<string>();

        ByteBuilder key(16);
        ByteBuilder data(16);
        ByteBuilder iv(8);

        DevCommand::FromAscii(sKey.c_str(), key);
        DevCommand::FromAscii(sData.c_str(), data);
        DevCommand::FromAscii(sIV.c_str(), iv);

        ByteBuilder buff(32);
        bool isCBC = !(iv.IsEmpty());
        bool bOK = true;
        if(isCBC)
        {
            bOK = SM4_Provider::CBC_Encrypt(key, iv, data, buff);
        }
        else
        {
            bOK = SM4_Provider::ECB_Encrypt(key, data, buff);
        }
        if(bOK)
        {
            rlt.Put("DATA", ArgConvert::ToString(buff));
        }
        return bOK;
    }
    /**
     * @brief 解密数据
     * @date 2017-05-17 14:02
     * 
     * @param [in] KEY : hex 解密密钥(16字节)
     * @param [in] IV : hex [default:空] IV值(16字节)
     * @warning IV不存在或值为空时表示使用ECB方式
     *
     * @param [in] DATA : hex 需要解密的数据
     * 
     * @retval DATA : hex 解密后的数据
     */
    LC_CMD_METHOD(Decrypt)
    {
        string sKey = arg["KEY"].To<string>();
        string sData = arg["DATA"].To<string>();
        string sIV = arg["IV"].To<string>();

        ByteBuilder key(16);
        ByteBuilder data(16);
        ByteBuilder iv(8);

        DevCommand::FromAscii(sKey.c_str(), key);
        DevCommand::FromAscii(sData.c_str(), data);
        DevCommand::FromAscii(sIV.c_str(), iv);

        ByteBuilder buff(32);
        bool isCBC = !(iv.IsEmpty());
        bool bOK = true;
        if(isCBC)
        {
            bOK = SM4_Provider::CBC_Decrypt(key, iv, data, buff);
        }
        else
        {
            bOK = SM4_Provider::ECB_Decrypt(key, data, buff);
        }
        if(bOK)
        {
            rlt.Put("DATA", ArgConvert::ToString(buff));
        }
        return bOK;
    }
};
//--------------------------------------------------------- 
} // nemespace driver
} // namespace application
} // namespace zhou_yb
//--------------------------------------------------------- 
#endif // _LIBZHOUYB_SM4CMDDRIVER_H_
//========================================================= 